package ext.tianma.part;

import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Locale;

import org.apache.log4j.Logger;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;
import ext.com.iba.IBAUtil;
import ext.tianma.util.IbaAttributeUtil;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.collections.WTArrayList;
import wt.log4j.LogR;
import wt.method.RemoteAccess;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.vc.Iterated;
import wt.vc.config.ConfigHelper;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;

/**
 * 用于生成半成品料号申请时生成虚拟料号 虚拟料号标识：虚拟料号均使用10位数字编码，为区别于物料编码，在虚拟料号前段默认加字母“X”；
 * 
 * @author laichao_sun
 *
 */

public class VirtualPartNumber implements RemoteAccess, Serializable {
	private static final Logger log = LogR.getLogger(VirtualPartNumber.class.getName());
	private static final long serialVersionUID = -2076953656294438627L;
	public static WTProperties wtProperties;
	public static String CLASSNAME = "";
	private static WTArrayList partList3 = new WTArrayList();
	static {
		CLASSNAME = VirtualPartNumber.class.getName();
		try {
			wtProperties = WTProperties.getLocalProperties();
		} catch (java.io.IOException ioe) {
			ioe.printStackTrace();
		}
	}

	/**
	 * 半成品创建生成虚拟料号
	 * 
	 * @param obj PBO
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static void setVirtualPartNumber(WTPart part) throws WTException {
		//System.out.println("开始生成虚拟料号-slc");
		Workbook we = null;
		InputStream in = null;
		try {
			// 加工方式及薄化前后厚度
			String pMAT = IbaAttributeUtil.getAttributeValue(part, "processingModeAndThickness");
			if (!(pMAT.indexOf("委外") != -1)) {
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("不是委外半成品,不生成虚拟料号");
				return;
			} else if(pMAT.contains("封胶")||pMAT.contains("切割")||pMAT.contains("返修")||pMAT.contains("打码")){
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("包含封胶、切割、返修、打码等工艺,不生成虚拟料号");
				return;
			}else {
				String VirtualNumber = "";
				String path = (WTProperties.getLocalProperties()).getProperty("ext.tianma.cfg.VirtualPartNumber");
				in = new FileInputStream(path);
				we = WorkbookFactory.create(in);
				if (null == path || path.equals("")) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查!");
				}
				if (null == in || null == we) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查");
				}
				// 切割方式
				String cuttingMode = IbaAttributeUtil.getAttributeValue(part, "cuttingMode");
				// 是否镀膜
				String coating = "";
				if (pMAT.indexOf("镀膜") != -1) {
					coating = "镀膜";
				} else {
					coating = "不镀膜";
				}
				// 镀膜类型（非C7/C8半成品请选NA）
				String Coatingtype = IbaAttributeUtil.getAttributeValue(part, "Coatingtype");
				// 料号生效地
				String pNES = IbaAttributeUtil.getAttributeValue(part, "partNumberEffectiveSite");
				VirtualNumber = "X" + getCode(we.getSheetAt(0), cuttingMode, pMAT, coating, Coatingtype, pNES);
				//System.out.println("SLC=====虚拟料号=====>>"+VirtualNumber);
				if (VirtualNumber.contains("NA")) {
					//System.out.println("请联系上级确认编码规则!");
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "");		
					// 弹出一个页面提示虚拟料号编码待确认
					//throw new WTException("该半成品在此生效地没有这种镀膜类型,请确认后,重新申请!");
					return;
				}
				if (VirtualNumber.length() != 11||VirtualNumber.contains("null")) {
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
					//System.out.println("半成品虚拟料号生成不成功，请联系管理员确认虚拟料号生成规则! "+"料号为:"+part.getNumber());
					//throw new WTException("半成品虚拟料号生成不成功，请联系管理员确认虚拟料号生成规则!");
					return;
				}
				Hashtable<String, String> values = new Hashtable<String, String>();
				values = addToHashtable(values, "virtualNumber", VirtualNumber);
				//System.out.println("values===>>" + values);
				IBAUtil.setSoftTypeIBAValues(part, values);
				PersistenceHelper.manager.refresh(part);
				//System.out.println("Debug   设置半成品虚拟料号成功====>" + VirtualNumber);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} finally {
			close(in);
		}

	}

	/**
	 * 检出检入时生成半成品虚拟料号
	 * 
	 * @param obj PBO
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static void setVirtualPartNumberThree(WTPart part) throws WTException {
		//System.out.println("SLC ==检出检入时生成半成品虚拟料号==>");
		Workbook we = null;
		InputStream in = null;
		try {
			// 加工方式及薄化前后厚度
			String pMAT = IbaAttributeUtil.getAttributeValue(part, "processingModeAndThickness");
			if (!(pMAT.indexOf("委外") != -1)) {
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("不是委外半成品,不生成虚拟料号");
				return;
			} else if(pMAT.contains("封胶")||pMAT.contains("切割")||pMAT.contains("返修")||pMAT.contains("打码")){
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("包含封胶、切割、返修、打码等工艺,不生成虚拟料号");
				return;
			}else {
				String VirtualNumber = "";
				String path = (WTProperties.getLocalProperties()).getProperty("ext.tianma.cfg.VirtualPartNumber");
				in = new FileInputStream(path);
				we = WorkbookFactory.create(in);
				if (null == path || path.equals("")) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查!");
				}
				if (null == in || null == we) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查");
				}
				// 切割方式
				String cuttingMode = IbaAttributeUtil.getAttributeValue(part, "cuttingMode");
				// 是否镀膜
				String coating = "";
				if (pMAT.indexOf("镀膜") != -1) {
					coating = "镀膜";
				} else {
					coating = "不镀膜";
				}
				// 镀膜类型（非C7/C8半成品请选NA）
				String Coatingtype = IbaAttributeUtil.getAttributeValue(part, "Coatingtype");
				// 料号生效地
				String pNES = IbaAttributeUtil.getAttributeValue(part, "partNumberEffectiveSite");
				VirtualNumber = "X" + getCode(we.getSheetAt(0), cuttingMode, pMAT, coating, Coatingtype, pNES);
				//System.out.println("SLC=====虚拟料号=====>>"+VirtualNumber);
				if (VirtualNumber.contains("NA")) {
					//System.out.println("请联系上级确认编码规则!");
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "NA");
					return;
					// 弹出一个页面提示虚拟料号编码待确认
					//throw new WTException("该半成品在此生效地没有这种镀膜类型,请确认后,重新修改!");
				}
				if (VirtualNumber.length() != 11||VirtualNumber.contains("null")) {
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "NA");
					//System.out.println("半成品虚拟料号生成不成功，请联系管理员确认虚拟料号生成规则! "+"料号为:"+part.getNumber());
					return;
					//throw new WTException("半成品虚拟料号生成不成功，请联系管理员确认虚拟料号生成规则!");
				}
				Hashtable<String, String> values = new Hashtable<String, String>();
				values = addToHashtable(values, "virtualNumber", VirtualNumber);
				//System.out.println("values===>>" + values);
				IBAUtil.setSoftTypeIBAValues(part, values);
				PersistenceHelper.manager.refresh(part);
				//System.out.println("Debug   设置半成品虚拟料号成功====>" + VirtualNumber);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} finally {
			close(in);
		}
		
	}
	/**
	 * 同步Degisn视图下的半成品虚拟料号到其他视图
	 * 
	 * @param obj PBO
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static void setVirtualPartNumberTwo(WTPart part) throws WTException {
		//System.out.println("SLC ==同步Degisn视图下的半成品虚拟料号到其他视图==>");
		WTArrayList partList2 = new WTArrayList();
		// 获取最新的Design视图
		WTPart partleast = getLatestPartByPartMaster((WTPartMaster) part.getMaster());
		// 获取除Design的其他视图的部件
		partList2 = ext.tianma.part.PartWorkflowUtil.getAllPartViews(partleast);
		
		generateVirtualPartNumber(part, partList2);
		
	}
	/** 
	 * 用于同步其他视图下的部件的虚拟料号
	 * @param part
	 * @param partList2
	 */
	private static void generateVirtualPartNumber(WTPart part, WTArrayList partList2){
		try {
		//System.out.println("SLC ===开始判断部件的源是否为制造==>");
		String source = part.getSource().getDisplay(Locale.CHINA);
		//System.out.println("SLC ===Design部件的源==>" + source);
		// 用于存源是不是制造的部件
		WTArrayList partListB = new WTArrayList();
		// 用于存源是制造的部件
		WTArrayList partListC = new WTArrayList();

		for (int j = 0; j < partList2.size(); j++) {
			ObjectReference partref = (ObjectReference) partList2.get(j);
			Object partobj = partref.getObject();
			// 每个非Design视图下的部件
			WTPart part2 = (WTPart) partobj;
			//System.out.println("SLC ===非Design部件的信息=>" + part2.getNumber() + "|" + part2.getSource());
			String source2 = part2.getSource().getDisplay(Locale.CHINA);
			if (!"制造".equals(source2)) {
				partListB.add(part2);
			}
			if ("制造".equals(source2)) {
				partListC.add(part2);
			}
		}
		// 非制造的个数
		int B = partListB.size();
		// 制造的个数
		int C = partListC.size();
		//System.out.println("SLC =======非Design下的部件数==>" + partList2.size() + " |B:" + B + " |C:" + C);
		// 所有视图下的部件的源都为制造
		if (partList2.size() == C && B == 0) {
			for (int j = 0; j < partList2.size(); j++) {
				ObjectReference partref = (ObjectReference) partList2.get(j);
				Object partobj = partref.getObject();
				// 每个非Design视图下的部件
				WTPart part2 = (WTPart) partobj;
				String pMAT = IbaAttributeUtil.getAttributeValue(part2, "processingModeAndThickness");
				if (!(pMAT.indexOf("委外") != -1)) {
					IBAUtil.forceSetIBAValue(part2, "virtualNumber", "");
					continue;
				}
				setVirtualPartNumberFour(part2);
			}

		} else if (C > 1 && B > 0) {
			String meg = "非Design下的所有视图部件,包含多个部件源是制造的及源是非制造的,无法确定虚拟料号为哪一个,请看料号自主确认!";
			//System.out.println(meg);
			for (int j = 0; j < partList2.size(); j++) {
				ObjectReference partref = (ObjectReference) partList2.get(j);
				Object partobj = partref.getObject();
				// 每个非Design视图下的部件
				WTPart part2 = (WTPart) partobj;
				IBAUtil.forceSetIBAValue(part2, "virtualNumber", "");
			}
		} else if (C == 1 && B > 0) {
			String virtualPartNumber = "";
			int D = 0;
			for (int j = 0; j < partListC.size(); j++) {
				ObjectReference partref = (ObjectReference) partListC.get(j);
				Object partobj = partref.getObject();
				// 每个非Design视图下的部件
				WTPart part2 = (WTPart) partobj;
				String pMAT = IbaAttributeUtil.getAttributeValue(part2, "processingModeAndThickness");
				if (!(pMAT.indexOf("委外") != -1)) {
					IBAUtil.forceSetIBAValue(part2, "virtualNumber", "");
					D = 1;
					continue;
				}
				virtualPartNumber = setVirtualPartNumberFour(part2);
			}
			for (int j = 0; j < partListB.size(); j++) {
				if (D == 1) {
					String meg = "只有一个源为制造的,但是没有生成虚拟料号,不是委外加工方式,所以所有非Design视图 不生成虚拟料号";
					//System.out.println(meg);
					break;
				}
				ObjectReference partref = (ObjectReference) partListB.get(j);
				Object partobj = partref.getObject();
				// 每个非Design视图下的部件
				WTPart part2 = (WTPart) partobj;
				String pMAT = IbaAttributeUtil.getAttributeValue(part2, "processingModeAndThickness");
				if (!(pMAT.indexOf("委外") != -1)) {
					IBAUtil.forceSetIBAValue(part2, "virtualNumber", "");
					continue;
				}
				Hashtable<String, String> values = new Hashtable<String, String>();
				values = addToHashtable(values, "virtualNumber", virtualPartNumber);
				//System.out.println("values===>>" + values);
				IBAUtil.setSoftTypeIBAValues(part2, values);
				PersistenceHelper.manager.refresh(part2);
			}
		} else if (C == 0 && B > 0) {
			String meg = "非Design下的所有视图部件,所有的部件的源是非制造的,无法确定虚拟料号为哪一个,请看料号自主确认!";
			//System.out.println(meg);
			for (int j = 0; j < partList2.size(); j++) {
				ObjectReference partref = (ObjectReference) partList2.get(j);
				Object partobj = partref.getObject();
				// 每个非Design视图下的部件
				WTPart part2 = (WTPart) partobj;
				IBAUtil.forceSetIBAValue(part2, "virtualNumber", "");
			}
		}
		
		//System.out.println("SLC ===同步Design部件成功==>" +"非制造的个数:"+B+" | "+"制造的个数:"+C);
		
		}catch(WTException e) {
			
		}

	}
	/**
	 * 用于同步虚拟料号属性时生成其他视图下的虚拟料号
	 * @param part
	 * @return
	 * @throws Exception
	 */
	public static String setVirtualPartNumberFour(WTPart part){
		//System.out.println("开始刷新虚拟料号-slc");
		Workbook we = null;
		InputStream in = null;

		try {
			// 加工方式及薄化前后厚度
			String pMAT = IbaAttributeUtil.getAttributeValue(part, "processingModeAndThickness");
			if (!(pMAT.indexOf("委外") != -1)) {
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("不是委外半成品,不生成虚拟料号");
				return "";
			} else if (pMAT.contains("封胶") || pMAT.contains("切割") || pMAT.contains("返修") || pMAT.contains("打码")) {
				IBAUtil.forceSetIBAValue(part, "virtualNumber", "");
				//System.out.println("包含封胶、切割、返修、打码等工艺,不生成虚拟料号");
				return "";
			} else {
				String VirtualNumber = "";
				String path = (WTProperties.getLocalProperties()).getProperty("ext.tianma.cfg.VirtualPartNumber");
				in = new FileInputStream(path);
				we = WorkbookFactory.create(in);
				if (null == path || path.equals("")) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查!");
				}
				if (null == in || null == we) {
					throw new WTException("没有获取到半成品虚拟料号的配置路径，请检查");
				}
				// 切割方式
				String cuttingMode = IbaAttributeUtil.getAttributeValue(part, "cuttingMode");
				// 是否镀膜
				String coating = "";
				if (pMAT.indexOf("镀膜") != -1) {
					coating = "镀膜";
				} else {
					coating = "不镀膜";
				}
				// 镀膜类型（非C7/C8半成品请选NA）
				String Coatingtype = IbaAttributeUtil.getAttributeValue(part, "Coatingtype");
				// 料号生效地
				String pNES = IbaAttributeUtil.getAttributeValue(part, "partNumberEffectiveSite");
				VirtualNumber = "X" + getCode(we.getSheetAt(0), cuttingMode, pMAT, coating, Coatingtype, pNES);
				//System.out.println("SLC=====虚拟料号=====>>" + VirtualNumber);
				if (VirtualNumber.contains("NA")) {
					String string = "该半成品在此生效地没有这种镀膜类型";
					//System.out.println(string);
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "NA");
					return "";
				}
				if (VirtualNumber.length() != 11 || VirtualNumber.contains("null")) {
					IBAUtil.forceSetIBAValue(part, "virtualNumber", "NA");
					//System.out.println("半成品虚拟料号生成不成功，请联系管理员确认虚拟料号生成规则! "+"料号为:"+part.getNumber());
					return "";
				}
				Hashtable<String, String> values = new Hashtable<String, String>();
				values = addToHashtable(values, "virtualNumber", VirtualNumber);
				//System.out.println("values===>>" + values);
				IBAUtil.setSoftTypeIBAValues(part, values);
				PersistenceHelper.manager.refresh(part);
				// 获取最新部件
				WTPart partleast = getLatestPartByPartMaster((WTPartMaster) part.getMaster());

				partList3.add(partleast);

				//System.out.println("Debug 设置半成品虚拟料号成功====>" + VirtualNumber);
				
				return VirtualNumber;
			}

		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
			log.error(e.getMessage(), e);
		} finally {
			close(in);
		}
		return "";

	}
	/**
	 * 获取最新的部件
	 * @param paramWTPartMaster
	 * @return
	 * @throws WTException
	 */
	@SuppressWarnings("deprecation")
	public static WTPart getLatestPartByPartMaster(WTPartMaster paramWTPartMaster) throws WTException {
		Iterated localIterated = null;
		boolean bool = false;
		LatestConfigSpec localLatestConfigSpec = new LatestConfigSpec();

		QueryResult localQueryResult = ConfigHelper.service.filteredIterationsOf(paramWTPartMaster,
				localLatestConfigSpec);
		if ((localQueryResult != null) && (localQueryResult.size() <= 0)) {
			ConfigSpec localConfigSpec = ConfigHelper.service.getDefaultConfigSpecFor(WTPartMaster.class);
			localQueryResult = ConfigHelper.service.filteredIterationsOf(paramWTPartMaster, localConfigSpec);
		}

		while ((localQueryResult.hasMoreElements()) && (!bool)) {
			localIterated = (Iterated) localQueryResult.nextElement();
			bool = localIterated.isLatestIteration();
		}
		return (WTPart) localIterated;
	}

	/**
	 * 获取编码
	 * 
	 * @param sheet sheet对象
	 * @param name  名称
	 * @return 编码
	 * @throws WTException
	 */
	public static String getCode(Sheet sheet, String cuttingMode, String pMAT, String coating, String Coatingtype,
			String pNES) throws WTException {
		// 薄化厚度
		String thickness = "";
		if (pMAT.indexOf("薄化") != -1) {
			thickness = pMAT.substring(pMAT.indexOf("-") + 1);
			//System.out.println("薄化厚度" + thickness);
		} else {
			thickness = "0";
		}
		String bake = "";
		if (pMAT.indexOf("烘烤") != -1) {
			bake = "烘烤";
		} else {
			bake = "不烘烤";
		}
		String polishing = "";
		if (pMAT.indexOf("抛光") != -1) {
			polishing = "抛光";
		} else {
			polishing = "不抛光";
		}
		String code = "";
		for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
			Row row = sheet.getRow(i);
			String temp = getCellValue(row.getCell(0)).trim();
			if (null == temp || temp.equals("")) {
				continue;
			} else {
				if (temp.equals(pNES)) {
					code = getCellValue(row.getCell(1)).trim();
					continue;
				} else if (temp.equals(cuttingMode)) {
					code = code + getCellValue(row.getCell(1)).trim();
					continue;
				} else if (temp.equals(thickness)) {
					code = code + getCellValue(row.getCell(1)).trim();
					continue;
				} else if (temp.contains(coating) || temp.contains(Coatingtype) || temp.contains(pNES)) {
					if (temp.equals(coating)) {
						code = code + getCellValue(row.getCell(1)).trim();
						continue;
					} else {
						if (temp.equals(coating + Coatingtype + pNES)) {
							code = code + getCellValue(row.getCell(1)).trim();
							continue;
						}
					}
				} else if (temp.equals(bake)) {
					code = code + getCellValue(row.getCell(1)).trim();
					continue;
				} else if (temp.equals(polishing)) {
					code = code + getCellValue(row.getCell(1)).trim();
					break;
				}
			}
		}

		return code;

	}

	/**
	 * 获取单元格中的信息
	 * 
	 * @param cell 单元格
	 * @return 主要参数信息
	 * @throws Exception
	 */
	public static String getCellValue(Cell cell) throws WTException {
		String value = "";
		try {
			if (null == cell) {
				return "";
			}
			switch (cell.getCellType()) {
			case XSSFCell.CELL_TYPE_NUMERIC:
				value = Double.toString(cell.getNumericCellValue());
				break;
			case XSSFCell.CELL_TYPE_STRING:
				value = cell.getStringCellValue();
				break;
			case XSSFCell.CELL_TYPE_BLANK:
				value = "";
				break;
			case XSSFCell.CELL_TYPE_BOOLEAN:
				value = Boolean.toString(cell.getBooleanCellValue());
				break;
			case XSSFCell.CELL_TYPE_FORMULA:
				try {
					value = String.valueOf(cell.getNumericCellValue());
				} catch (Exception e) {
					value = cell.getStringCellValue();
				}
				break;
			default:
				break;
			}
		} catch (Exception e) {
		}

		return value.trim();
	}

	/**
	 * 实现Hashtable添加数据时不会出现空指针异常
	 * 
	 * @param hashtable
	 * @param key
	 * @param value
	 * @return
	 */
	private static Hashtable<String, String> addToHashtable(Hashtable<String, String> hashtable, String key,
			String value) {
		if (key == null && hashtable != null) {
			return hashtable;
		}

		if (value == null && hashtable != null) {
			return hashtable;
		}

		if (key == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (value == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (hashtable == null) {
			hashtable = new Hashtable<String, String>();
		}
		hashtable.put(key, value);

		return hashtable;
	}

	/**
	 * 关闭资源
	 * 
	 * @param closeable
	 */
	public static void close(Closeable closeable) {
		try {
			if (closeable != null) {
				closeable.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}